package com.itheima.mapper;

import com.itheima.pojo.User;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;

import java.sql.Date;
import java.util.List;
import java.util.Map;

/**
 * @author by itheima
 * @Date 2021/8/20
 * @Description 定义操纵user表的接口
 *  接口与xml映射文件绑定：
 *   1.接口的全限定名称要与xml映射文件中namespace（全局id）要保证一致
 *   2.接口中的方法名称要与xml映射文件的增删改查标签的属性id一致
 *      mybatis底层通过解析xml映射文件，就可以通过反射获取接口的信息，然后mybatis体层会为接口生成代理对象，
 *      每个方法都关联一个SQL
 *       以findUserById为例：
 *          代理方法的实现：
 *              获取去查询的sql:select * from user where id=?
 *              调用jdbc预编译对象发送sql模板
 *              调用接口方法时，传入值，底层预编译对象调用setxxx(参数索引，接口传入的值)
 *              执行查询
 *              获取ResultSet结果
 *              ORM映射，将结果集封装到User对象；
 */
public interface UserMapper {
    /**
     * 根据id查询用户信息
     * @param id
     * @return
     */
    User findUserById(Integer id);

    /**
     * 根据id查询用户信息
     * @param id
     * @return
     */
    User findUserById2(@Param("uId") Integer id);

    /**
     * 根据用户id查询用户名称
     * @param id
     * @return
     */
    String findUserNameById(Integer id);

    /**
     * 根据用户id查询生日
     * @param id
     * @return
     */
    Date findBirthdayById(Integer id);

    /**
     * 获取所有的用户信息
     * @return
     */
    List<User> findAll();

    /**
     * 插入用户信息
     * @param user
     * @return 获取受影响的行数
     */
    Integer insertUser(User user);

    /**
     * 更新用户信息
     * @param user
     * @return 返回受影响行数
     */
    Integer updateUser(User user);

    /**
     * 根据用户id删除用户信息
     * @param id
     */
    void deleteById(Integer id);

    User findByName(Date date);


    /**
     * 根据用户名称和性别查询用户信息
     * @param name
     * @param sex
     * @return
     */
    List<User> findByUserNameAndSex(@Param("userName") String name,@Param("sex") String sex);

    /**
     * map中存储用户名和性别信息，然后根据map中的信息进行查询
     * @param map
     * @return
     */
    List<User> findUserByMap(Map<String, Object> map);


    /**
     * 功能：插入用户信息，并且生成的主键回填到插入的对象下
     * @param user
     * @return 返回受影响行数
     */
    Integer addUserAndGetPk(User user);


    /**
     * 功能：插入用户信息，并且生成的主键回填到插入的对象下
     * @param user
     * @return 返回受影响行数
     */
    Integer addUserAndGetPk2(User user);

    /**
     * 根据表名称获取指定表下的航记录数
     * @param name
     * @return
     */
    Integer findCountByTableName(@Param("name") String name);

    /**
     * 根据id查询用户信息，信息封装到Map集合下
     * @param id
     * @return
     */
    Map<String, Object> findMapById(@Param("id") Integer id);

    /**
     * 查询所有数据，并封装到map集合下’
     * 让主键id的值作为key，value就是每一行的数据
     *  @MapKey("id"):指定查询中那一列的值作为key
     * @return
     */
    @MapKey("id")
    Map<String, User> findAllMap();

    /**
     *  List<Map>可以接收任意参数
     *  非必须，不推荐，维护性差
     * @return
     */
    List<Map> findAll2();


    /**
     * 使用resultMap标签实现查询
     * @param id
     * @return
     */
    User findUserById3(@Param("id")  Integer id);


    /**
     * 动态SQL,如果输入用户名称，则根查询性别为男的基础上，模糊搜搜
     * 否则，仅仅查询性别为男的用户信息
     * @param name
     * @return
     */
    List<User> findUsersByUserName(@Param("name") String name);


    /**
     * 根据用户名和地址动态查询
     * 	如果输入了用户名，则不论是否输入了地址，仅仅按照用户名模糊查找；
     * 	否则，如果输入了地址，则按照住址查找；
     * 	如果两者都没有输入则查找用户名为“孙悟空”的用户；
     * 	为了测试
     * 	测试3
     * @param name
     * @param address
     * @return
     */
    List<User> findUsersByUserNameAndAddress(@Param("name") String name,@Param("address") String address);


    /**
     * 根据用户名和地址综合查询
     *  使用where标签
     * @param name
     * @param address
     * @return
     */
    List<User> getUsersByNameAndAddress(@Param("name") String name,@Param("address") String address);


    /**
     * 仅仅更新出入对象中属性不为null的值
     * @param user
     * @return
     */
    Integer updateUserByExistAttribute(User user);

    /**
     * 根据id集合批量查询用户信息
     * @param ids
     * @return
     */
    List<User> findByIds(@Param("ids") List<Integer> ids);

    /**
     * 根据id集合批量删除
     * @param ids
     * @return
     */
    Integer deleteByIds(@Param("ids") List<Integer> ids);

    /**
     * 批量插入用户数据
     * @param users
     * @return
     */
    Integer insertUsers(@Param("users") List<User> users);
}
